using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Deloitte.Data;
using Deloitte.MSExcel;
using Deloitte.Common;

namespace Deloitte.Windows.Forms
{
    public partial class DataForm : Form
    {
        int blankTableNameCount = 0;
        private List<TabPage> tabPages;
        private System.Collections.Hashtable tableHash;
        private bool isOpeningInBackground = false;
        private int fileOpening=0, filesToOpen=0;       
        public DataForm()
        {
            InitializeComponent();
            CommonConstructorCode();
        }
        public DataForm(DataTable table)
        {
            InitializeComponent();
            CommonConstructorCode();
            this.AddNewDataTab(table);
        }
        public DataForm(DataSet dataSet)
        {
            InitializeComponent();
            CommonConstructorCode();
            this.AddDataSetTables(dataSet);
        }
        private void CommonConstructorCode()
        {
            this.tabControl.ControlAdded += new ControlEventHandler(tabControl_ControlAdded);
            this.tabControl.ControlRemoved += new ControlEventHandler(tabControl_ControlRemoved);
            this.openFileBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(openFileBackgroundWorker_ProgressChanged);
            this.openFileBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(openFileBackgroundWorker_RunWorkerCompleted);
        }

        void tabControl_ControlRemoved(object sender, ControlEventArgs e)
        {
            if (e.Control is TabPage)
            {
                if (this.tabControl.TabPages.Count <= 0) { e.Control.Size = new Size((int)(this.tabControl.Width * .97), (int)(this.tabControl.Height * .97)); }
                this.miClose.Enabled = true;
            }
        }

        void tabControl_ControlAdded(object sender, ControlEventArgs e)
        {
            if (e.Control is TabPage)
            {
                if (this.tabControl.TabPages.Count > 0) { this.miClose.Enabled = true; }
                else { this.miClose.Enabled = false; }
            }
        }
        private void AddNewDataTab(DataTable table)
        {
            try
            {                
                TabPage tabPage = new TabPage();
                if (table.TableName == null || table.TableName == string.Empty || table.TableName == "")
                {
                    table.TableName = "Table" + this.blankTableNameCount;
                    this.blankTableNameCount++;
                }
                tabPage.Name = table.TableName;                
                tabPage.Text = table.TableName;
                if (!this.isOpeningInBackground)
                {
                    AddTabPage(table, tabPage);
                }
                else
                {
                    if(this.tabPages ==null){this.tabPages = new List<TabPage>();}
                    if(this.tableHash==null){this.tableHash= new System.Collections.Hashtable();}
                    this.tabPages.Add(tabPage);
                    this.tableHash.Add(tabPage, table);
                }
            }
            catch(Exception ex){ExceptionHandling.ShowMessageBox(ex);}
        }

        private void AddTabPage(DataTable table, TabPage tabPage)
        {
            this.tabControl.Controls.Add(tabPage);
            Controls.DataGridViewControl ctl = new Controls.DataGridViewControl(table);
            //Controls.OKCancelControl ctl = new Controls.OKCancelControl(this);
            //set the size and the anchor
            ctl.Location = new System.Drawing.Point(1, 1);
            ctl.Size = new Size(tabPage.Width, tabPage.Height);
            ctl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
            | System.Windows.Forms.AnchorStyles.Left)
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tabControl.TabPages[tabPage.Name].Controls.Add(ctl);
        }

        private void miOpen_Click(object sender, EventArgs e)
        {
            OpenDataSourceDialog();
        }
        public void OpenDataSet(DataSet dataSet)
        {
            AddDataSetTables(dataSet);
        }
        public void OpenDataSourceDialog()
        {
            try
            {                
                if (this.openFileDialog1 == null) this.openFileDialog1 = new OpenFileDialog();
                this.openFileDialog1.Title = @"Open Data Source";
                this.openFileDialog1.Filter = @"XML File (*.xml)|*.xml|CSV Files (*.csv)|*.csv|Excel Range (*.xls)|*.xls";
                //todo: add a filter on the dialog for excel files and ODBC Data sources
                if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    this.isOpeningInBackground = true;
                    string file = string.Empty;
                    string[] files = this.openFileDialog1.FileNames;
                    this.filesToOpen = files.GetLength(0);                    
                    this.toolStripStatusLabel1.Text = "Opening " + this.filesToOpen + " File(s)";
                    this.miOpen.Enabled = false;
                    this.openFileBackgroundWorker.RunWorkerAsync(files);
                }
            }
            catch (Exception ex) { ExceptionHandling.ShowMessageBox(ex); }
        }

        private void OpenDataFile(string file)
        {
            if (file.ToLower().EndsWith("xml"))
            {
                DataSet ds = Utility.LoadXMLFileToDataSet(file);
                AddDataSetTables(ds);
            }
            else if (file.ToLower().EndsWith("csv"))
            {
                DataSet ds = new DataSet();
                bool hasHeaders = false;
                if (MessageBox.Show("Are headers included?", "CSV File", MessageBoxButtons.YesNo) == DialogResult.Yes){hasHeaders = true;}
                DataTable2 table= new DataTable2(file, hasHeaders);
                ds.Tables.Add(table);
                AddDataSetTables(ds);
            }
            else if (file.ToLower().EndsWith("xls"))
            {            
                Microsoft.Office.Interop.Excel.Application xlApp = null;
                Microsoft.Office.Interop.Excel.Workbook xlBook = null;
                Microsoft.Office.Interop.Excel.Worksheet xlSheet = null;
                Microsoft.Office.Interop.Excel.Range xlRange = null;
                try{
                StringInputForm inputForm = new StringInputForm("Please enter the name of the worksheet containing the range");
                 xlApp = new Microsoft.Office.Interop.Excel.Application();
                System.Reflection.Missing missing = System.Reflection.Missing.Value;
                 xlBook = xlApp.Workbooks.Open(file,missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing,missing);
                 if (inputForm.ShowDialog() == DialogResult.OK)
                 {
                     if (ExcelHelper.ValidateSheet(xlBook, inputForm.Response) == true)
                     {
                         xlSheet = (Microsoft.Office.Interop.Excel.Worksheet) xlBook.Worksheets.get_Item(inputForm.Response);
                         //get the range
                         inputForm.Prompt = "Please enter the range to view";
                         inputForm.Response = string.Empty;
                         if (inputForm.ShowDialog() == DialogResult.OK)
                         {
                             
                             if (ExcelHelper.ValidateRange(xlSheet, inputForm.Response) == true)
                             {
                                 xlRange = xlSheet.get_Range(inputForm.Response, System.Reflection.Missing.Value);
                                 bool hasHeaders = false;
                                 if (MessageBox.Show("Are headers included?", "Excel Range", MessageBoxButtons.YesNo) == DialogResult.Yes) { hasHeaders = true; }
                                 string[] cols = null;
                                 DataTable table = (DataTable)ExcelHelper.LoadRangeToDataTable(xlRange, hasHeaders, true, cols);
                                 DataSet ds = new DataSet();
                                 ds.Tables.Add(table);
                                 AddDataSetTables(ds);
                             }
                         }
                     }
                 }
                }
                catch(Exception){}
                finally{
                    if(xlBook!=null){xlBook.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                    xlBook = null;
                    }
                    if(xlApp!=null){xlApp = null;}
                }
            }
        }

        private void AddDataSetTables(DataSet ds)
        {
            if (ds != null) foreach (DataTable table in ds.Tables) { this.AddNewDataTab(table); }
        }

        private void miClose_Click(object sender, EventArgs e)
        {
            this.tabControl.TabPages.Remove(this.tabControl.SelectedTab);
        }

        private void openFileBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] files = (string[])e.Argument;
            string file = string.Empty;
            for (int i = 0; i < this.filesToOpen; i++)
            {
                file = files[i];
                this.fileOpening = i + 1;
                this.openFileBackgroundWorker.ReportProgress(System.Convert.ToInt32((double)(((double)this.fileOpening / (double)this.filesToOpen) * 100.0)));
                this.OpenDataFile(file);
            }
                  
        }
        void openFileBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.toolStripProgressBar1.Value = e.ProgressPercentage;
        }
        void openFileBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                foreach (TabPage tabPage in this.tabPages)
                {
                    this.AddTabPage((DataTable)this.tableHash[tabPage], tabPage);
                }
            }
            catch (Exception ex) { ExceptionHandling.ShowMessageBox(ex); }
            finally
            {                                
                this.tabPages.Clear();
                this.tableHash.Clear();
                this.isOpeningInBackground = false;
                this.toolStripProgressBar1.Value = 0;
                this.toolStripStatusLabel1.Text = "Ready";
                this.miOpen.Enabled = true;
            }
        }

        private void menuItem6_Click(object sender, EventArgs e)
        {
            foreach (Control ctl in this.tabControl.SelectedTab.Controls)
            {
                if (ctl is Controls.DataGridViewControl)
                {
                    Controls.DataGridViewControl gridControl = (Controls.DataGridViewControl)ctl;
                    gridControl.SaveViewToXML();
                }

            }
        }

    }
}